home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / blix / blixui.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.2 KB  |  345 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*_______________________________________________________________________
  18.  |
  19.  | blixui.c - a faster ui and event handling
  20.  |
  21.  | this is based on ui.c and event.c, but largely rewritten, so it
  22.  | does nothing more then nessecarry, and uses a switch statement,
  23.  | instead of repeated testing (which is less flexible, but a lot
  24.  | faster)
  25.  | The ui.c and event.c programs were written by Gavin Bell, 1988
  26.  |
  27.  | (c) 1994 frans van hoesel    Xtreme Graphics Software
  28.  |                              hoesel@chem.rug.nl
  29.  |
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <math.h>
  35. #include <gl/gl.h>
  36. #include <gl/device.h>
  37. #include "config.h"
  38. #include "blix.h"
  39. #include "blixsound.h"
  40. #include "blixui.h"
  41. #include "blixmenu.h"
  42.  
  43. /* Externally visible state: */
  44. int ui_quiet = FALSE;
  45. int ui_noisy = TRUE;
  46. int putbomb = 0;            /* set to 1 when user hits space bar */
  47. int exitflag = 0;        /* Becomes 1 when user quits */
  48. int uimode = MODE2D;
  49.  
  50. /* States global to only this file */
  51. static int zoomflag = FALSE;    /* When rotating with middle mouse */
  52. static int panflag = FALSE;    /* Left AND Middle, zoom */
  53. static int rotateflag = FALSE;    /* Left mouse, pan */
  54. static int mouse_noisy = FALSE;    /* Interacting with mouse */
  55. long sizex, sizey;        /* window size */
  56. static long origx, origy;       /* window position */
  57. static short omx = (-1);        /* old and new mouse position */
  58. static short omy = (-1);        /* reset to -1 when mouse buttons go up */
  59. static short nmx = (-1);
  60. static short nmy = (-1);
  61. static int pop = 1;
  62.  
  63. /* local prototypes */
  64. static void mouse_ui(void);
  65.  
  66.  
  67. /*_________________________________________________________________________
  68.  |
  69.  | ui_to_worldspace - map mouse position
  70.  |
  71.  | Map mouse click sx, sy to a more convenient (-1.0,1.0)
  72.  | range, based on window size.
  73. */
  74.  
  75. static void ui_to_worldspace(short sx, short sy, float * wx, float * wy) {
  76.     (*wx) = (2.0 * sx) / (float) sizex - 1.0;
  77.     (*wy) = (2.0 * sy) / (float) sizey - 1.0;
  78. }
  79.  
  80. /*__________________________________________________________________
  81.  |
  82.  | ui - main event loop
  83.  |
  84.  | only returns when users exits.
  85.  |
  86. */
  87.  
  88. void ui(void) {
  89.     short s;
  90.     int device;
  91.     int state;
  92.     
  93.     while (exitflag == 0 && uimode == MODE3D ) {
  94.     if (qtest()) {
  95.         device = (int) qread(&s);
  96.         state = s;
  97.         switch (device) {
  98.         
  99.         case REDRAW:
  100.             reshapeviewport();
  101.             getsize(&sizex, &sizey);
  102.             getorigin(&origx, &origy);
  103.             draw_whatever();
  104.             break;
  105.  
  106.         case LEFTMOUSE:
  107.             if (state == DOWN) {
  108.             if (rotateflag == TRUE) {
  109.                 zoomflag = TRUE;
  110.                 rotateflag = FALSE; 
  111.             } else {
  112.                 panflag = TRUE;
  113.                 ui_noisy = mouse_noisy = TRUE;
  114.                 ui_quiet = !ui_noisy;
  115.             }
  116.             } else {
  117.             /* 'officially' you should be rotating when
  118.              * you came from zoommode and released the
  119.              * left mouse button; that migth however be
  120.              * annoying because it migth be true that you
  121.              * simply released the left-moust 1 millisecond
  122.              * before the middle one. As a 'fix' turn
  123.              * everything off.
  124.              */
  125.             zoomflag = FALSE;
  126.             rotateflag = FALSE;
  127.             panflag = FALSE;
  128.             mouse_noisy = FALSE;
  129.             ui_noisy = rotateflag;
  130.             ui_quiet = !ui_noisy;
  131.             omx = omy = nmx = nmy = (-1);
  132.             }
  133.             mouse_ui();
  134.             break;
  135.         
  136.         case MIDDLEMOUSE:
  137.             if (state == DOWN) {
  138.             if (panflag == TRUE) {
  139.                 zoomflag = TRUE;
  140.                 panflag = FALSE;
  141.             } else {
  142.                 rotateflag = TRUE;
  143.                 mouse_noisy = TRUE;
  144.                 ui_noisy = TRUE;
  145.                 ui_quiet = !ui_noisy;
  146.             }
  147.             } else {
  148.             if (zoomflag == TRUE) {
  149.                 zoomflag = FALSE;
  150.                 panflag = TRUE;
  151.             } else {
  152.                 rotateflag = FALSE;
  153.                 mouse_noisy = FALSE;
  154.                 ui_noisy = panflag;
  155.                 ui_quiet = !ui_noisy;
  156.                 omx = omy = nmx = nmy = (-1);
  157.             }
  158.             }
  159.             /* don't call mouse_ui here; it makes the interface
  160.              * a bit tricky, because you might accidently cause
  161.              * a big rotation. Not calling it now will delay it
  162.              * by one frame
  163.              */
  164.             /*mouse_ui();*/
  165.             break;
  166.         
  167.         case RIGHTMOUSE:
  168.             if (state == DOWN && pop) {
  169.             do_menus();
  170.             }
  171.             break;
  172.             
  173.         case ESCKEY:
  174.             if (state == UP) {
  175.             exitflag = 1;
  176.             }
  177.             break;
  178.         
  179.         case SPACEKEY:
  180.         case BKEY: 
  181.             if (state == DOWN) {
  182.             putbomb = 1;
  183.             }
  184.             break;
  185.             
  186.         case WINQUIT:
  187.         case WINSHUT:
  188.             exitflag = 1;
  189.             break;
  190.         }            
  191.     } else {
  192.         if (mouse_noisy) {
  193.         mouse_ui();
  194.         } else {
  195.         spin_draw();
  196.         }
  197.     }
  198.     }
  199. }
  200.  
  201.  
  202. /*___________________________________________________________________
  203.  |
  204.  | mouse_ui - mouse interface
  205.  |
  206.  | maps the mouse coordinates on the virtual trackball, and calls
  207.  | the trackball rotine to do the rotation.
  208.  |
  209. */
  210.  
  211. static void mouse_ui(void) {
  212.     float r[4], t[3];
  213.  
  214.     if (mouse_noisy) {
  215.     nmx = (short) getvaluator(CURSORX);
  216.     if (omx == (-1)) omx = nmx;
  217.     nmy = (short) getvaluator(CURSORY);
  218.         if (omy == (-1)) omy = nmy;
  219.     if (panflag != 0) {
  220.         ui_to_worldspace((short)( nmx-origx), (short)(nmy-origy),
  221.         t+1, t+2);
  222.         t[0] = 0;
  223.         remember_view(r, t);
  224.     } else  if (zoomflag !=0 ) {
  225.         t[0] = 1;
  226.         t[2] = (float)(nmy-omy)/(float)sizey;
  227.         remember_view(r, t);
  228.     } else if (rotateflag != 0) {
  229.         float p1x, p1y, p2x, p2y ;
  230.         t[0] = 2;
  231.         ui_to_worldspace((short)( omx-origx), (short)(omy-origy),
  232.             &p1x, &p1y);
  233.         ui_to_worldspace((short)(nmx-origx), (short)(nmy-origy), &p2x, &p2y);
  234.         trackball(r, p1x, p1y, p2x, p2y);
  235.         remember_view(r, t);
  236.     }
  237.     omx = nmx; omy = nmy;
  238.     }
  239. }            
  240.  
  241.  
  242. /*_________________________________________________________________
  243.  |
  244.  | enter_redraw - queue a redraw event
  245.  |
  246. */
  247.  
  248. void enter_redraw(void) {
  249.     qenter(REDRAW, 0);
  250. }
  251.  
  252. /*__________________________________________________________________
  253.  |
  254.  | do_event - handle window events
  255.  |
  256.  | this routine is only used during the rather long initialization
  257.  | procedure. The events are initialized in init_ui
  258.  | it is called from player.c, but kept in this file for easy porting
  259.  |
  260. */
  261.  
  262. int do_event(void) {
  263.     short s;
  264.     int dev;
  265.     int state;
  266.     
  267.     while (qtest()) {
  268.     dev = (int)qread(&s);
  269.     state = s;
  270.     switch (dev) {
  271.         case ESCKEY:
  272.         if (s != 0)
  273.             return 0;
  274.         /* else run through to exit routine */
  275.         case WINQUIT:
  276.         case WINSHUT:
  277.         exit_program();
  278.         break;
  279.         case REDRAW:
  280.         reshapeviewport();
  281.         getsize(&sizex, &sizey);
  282.         getorigin(&origx, &origy);
  283.         draw_whatever2d();
  284.         break;
  285.         case SPACEKEY:
  286.         case LEFTMOUSE:
  287.         if (state == UP) {
  288.             return 1;
  289.         }
  290.         break;
  291.         case RIGHTMOUSE:
  292.         if (state == DOWN && pop) {
  293.             do_menus();
  294.         } else if (state == UP) {
  295.             return 1;
  296.         }
  297.         break;
  298.     }
  299.     }
  300.     return 0;
  301. }
  302.  
  303. /*__________________________________________________________________
  304.  |
  305.  | disable_pop - disable the display of the popup menu
  306.  |
  307.  | call this routine when handling popup menues, so you don't
  308.  | call them recursivly, which is not allowed by the GL.
  309.  |
  310. */
  311.  
  312. void disable_pop(void) {
  313.     pop = 0;
  314. }
  315.  
  316. void enable_pop(void) {
  317.     pop = 1;
  318. }
  319.  
  320.  
  321. /*___________________________________________________________________
  322.  |
  323.  | init_ui - initialize user interface
  324.  |
  325.  | call this routine once from the main program.
  326.  |
  327. */
  328.  
  329. void init_ui(void) {
  330.     getsize(&sizex, &sizey);    /* Gotta know where center of */
  331.     getorigin(&origx, &origy);    /* window is */
  332.     qdevice(ESCKEY);
  333.     qdevice(WINQUIT);
  334.     qdevice(WINSHUT);
  335.     qdevice(BKEY);            /* for the bombs from previous version of blix */
  336.     qdevice(SPACEKEY);            /* for the bombs */
  337.     qdevice(REDRAW);        /* Keep track of window size changes */
  338.     qdevice(LEFTMOUSE);
  339.     qdevice(MIDDLEMOUSE);
  340.     qdevice(RIGHTMOUSE);
  341.     /*qdevice(INPUTCHANGE);*/   /* I don't see any use for this */
  342.  
  343. }
  344.  
  345.